package pers.hxy.lookweather.view.activity;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.activity.EdgeToEdge;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.google.gson.Gson;
import com.qweather.sdk.bean.geo.GeoBean;
import com.qweather.sdk.bean.weather.WeatherDailyBean;
import com.qweather.sdk.bean.weather.WeatherHourlyBean;
import com.qweather.sdk.bean.weather.WeatherNowBean;

import java.util.ArrayList;
import java.util.List;

import pers.hxy.lookweather.R;
import pers.hxy.lookweather.bean.AqiNowBean;
import pers.hxy.lookweather.presenter.WeatherPresenter;
import pers.hxy.lookweather.presenter.impl.WeatherPresenterImpl;
import pers.hxy.lookweather.utils.IconUtil;
import pers.hxy.lookweather.utils.StringUtil;
import pers.hxy.lookweather.view.WeatherView;
import pers.hxy.lookweather.view.adapter.Weather7DRecyclerViewAdapter;
import pers.hxy.lookweather.view.adapter.WeatherHourlyRecyclerViewAdapter;

/**
 * 在这里显示天气信息以及与用户交互
 */
public class WeatherActivity extends AppCompatActivity implements WeatherView {
    private static final String TAG = "WeatherActivity";

    public static final String INTENT_KEY_LOCATION_ID = "location_id";
    public static final String INTENT_KEY_LOCATION_NAME = "location_name";
    public static final String INTENT_KEY_LOCATION_BEAN = "location_bean";

    // 用于测试
    private static final String DEFAULT_LOCATION_ID = "101200113";
    private static final String DEFAULT_LOCATION_NAME = "湖北省武汉市洪山区";

    /** 用于获取天气信息 */
    private WeatherPresenter presenter;

    /** 用于用户跳转到其它界面选择地点 */
    private ActivityResultLauncher launcherGetLocation;

    /** 当前位置 */
    private GeoBean.LocationBean currentLocationBean;

    private TextView tvLocationName;
    private TextView tvWeatherNowTitle;
    private ImageView ivWeatherNowIcon;
    private TextView tvWeatherNowText;
    private TextView tvWeatherNowTemp;
    private TextView tvWeatherNowOther;
    private TextView tvWeatherNow;
    private RecyclerView rvWeatherHourly;
    private TextView tvWeatherHourly;
    private RecyclerView rvWeather7D;
    private TextView tvAqiNow;
    private TextView tvAqiNowPollutantName;
    private TextView tvAqiNowPollutantValue;

    private WeatherHourlyRecyclerViewAdapter rvWeatherHourlyAdapter;
    private Weather7DRecyclerViewAdapter rvWeather7DAdapter;

    private void initViews() {
        Log.d(TAG, "initViews");
        tvLocationName = findViewById(R.id.tv_location_name);
        tvWeatherNowTitle = findViewById(R.id.tv_weather_now_title);
        ivWeatherNowIcon = findViewById(R.id.iv_weather_now_icon);
        tvWeatherNowText = findViewById(R.id.tv_weather_now_text);
        tvWeatherNowTemp = findViewById(R.id.tv_weather_now_temp);
        tvWeatherNowOther = findViewById(R.id.tv_weather_now_other);
        tvWeatherNow = findViewById(R.id.tv_weather_now);
        rvWeatherHourly = findViewById(R.id.rv_weather_hourly);
        tvWeatherHourly = findViewById(R.id.tv_weather_hourly);
        rvWeather7D = findViewById(R.id.rv_weather_7d);
        tvAqiNow = findViewById(R.id.tv_aqi_now_text);
        tvAqiNowPollutantName = findViewById(R.id.tv_aqi_now_pollutant_name);
        tvAqiNowPollutantValue = findViewById(R.id.tv_aqi_now_pollutant_value);

        // 这几个内容设为空，用作辅助界面设计
        tvWeatherNowTitle.setText("");
        tvWeatherNow.setText("");
        tvWeatherHourly.setText("");

        // 按一下显示地点的标签更新一次天气
        tvLocationName.setOnClickListener(v -> updateLocation(currentLocationBean));

        // 小时天气预报
        rvWeatherHourlyAdapter = new WeatherHourlyRecyclerViewAdapter(new ArrayList<>());
        rvWeatherHourly.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
        rvWeatherHourly.setAdapter(rvWeatherHourlyAdapter);

        // 7天天气预报
        rvWeather7DAdapter = new Weather7DRecyclerViewAdapter(new ArrayList<>());
        rvWeather7D.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
        rvWeather7D.setAdapter(rvWeather7DAdapter);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_weather);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });

        Log.d(TAG, "onCreate");

        initViews();

        presenter = new WeatherPresenterImpl(this);

        launcherGetLocation = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
            o -> {
                if (o.getResultCode() == RESULT_OK && o.getData() != null) {
                    // 如果收到LocationBean，就直接用，否则就用location_id从网络请求
                    String locationBeanJson = o.getData().getStringExtra(INTENT_KEY_LOCATION_BEAN);
                    Log.d(TAG, "launcher get location_bean_json " + StringUtil.isNull(locationBeanJson));
                    if (StringUtil.isNotNullOrEmpty(locationBeanJson)) {
                        Log.d(TAG, "launcher get location_bean_json " + locationBeanJson.length() + ": " + locationBeanJson);
                        GeoBean.LocationBean locationBean = new Gson().fromJson(locationBeanJson, GeoBean.LocationBean.class);
                        updateLocation(locationBean);
                    } else {
                        String location_id = o.getData().getStringExtra(INTENT_KEY_LOCATION_ID);
                        Log.d(TAG, "launcher get location_id=" + StringUtil.isNull(location_id));
                        if (StringUtil.isNotNullOrEmpty(location_id)) {
                            presenter.getGeo(location_id);
                        }
                    }
                }
            }
        );

        // 获取默认地点的天气
        presenter.getGeo(DEFAULT_LOCATION_ID);
    }

    @Override
    protected void onDestroy() {
        if (presenter != null) {
            presenter.destroy();
            presenter = null;
        }
        super.onDestroy();
        Log.d(TAG, "onDestroy");
    }

    @Override
    public void showSuccess(String msg) {
        Log.d(TAG, StringUtil.nonNull(msg, "success"));
//        Toast.makeText(getContext(), "获取天气成功！", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void showError(String msg) {
        Log.d(TAG, StringUtil.nonNull(msg, "error"));
        Toast.makeText(getContext(), "获取天气失败！" + StringUtil.nonNull(msg), Toast.LENGTH_SHORT).show();
    }

    /**
     * 更新位置，即更新所有组件的天气信息
     * @param locationBean 位置信息
     */
    private void updateLocation(GeoBean.LocationBean locationBean) {
        if (locationBean != null) {
            currentLocationBean = locationBean;
            String location_id = currentLocationBean.getId();
            presenter.getWeatherNow(location_id);
            presenter.getWeather24H(location_id);
            presenter.getWeather7D(location_id);
            presenter.getAqiNow(Double.parseDouble(currentLocationBean.getLat()), Double.parseDouble(currentLocationBean.getLon()));
            tvLocationName.setText(currentLocationBean.getName());
        }
    }

    @Override
    public void getGeo(GeoBean geoBean) {
        Log.d(TAG, "getGeo " + StringUtil.isNull(geoBean));
        if (geoBean == null) {
            return;
        }
        List<GeoBean.LocationBean> locationBeans = geoBean.getLocationBean();
        if (!locationBeans.isEmpty()) {
            updateLocation(locationBeans.get(0));
        }
    }

    /** 根据不同风的等级获取对应的名称 */
    private String getWindName(int level) {
        String[] names = getResources().getStringArray(R.array.beaufort_wind_names);
        int max_level = names.length - 1;
        level = Math.max(Math.min(level, max_level), 0);
        return names[level];
    }

    @Override
    public void getWeatherNow(WeatherNowBean weatherNowBean) {
        Log.d(TAG, "getWeatherNow " + StringUtil.isNull(weatherNowBean));
        if (weatherNowBean == null) return;

        WeatherNowBean.NowBaseBean bean = weatherNowBean.getNow();
//        StringBuilder sb = new StringBuilder(1024);
//        String updateTime = DateUtil.getCurrentTime("HH:mm:ss");
//        sb
//                .append("Location ID: ").append(currentLocationBean.getId()).append('\n')
//                .append("更新时间：").append(updateTime).append('\n')
//                .append("实况观测时间：").append(bean.getObsTime()).append('\n')
//                .append("体感温度：").append(bean.getFeelsLike()).append(" ℃\n")
//                .append("温度：").append(bean.getTemp()).append(" ℃\n")
//                .append("图标代码：").append(bean.getIcon()).append('\n')
//                .append("文字描述：").append(bean.getText()).append('\n')
//                .append("风向（360角度）：").append(bean.getWind360()).append('\n')
//                .append("风向：").append(bean.getWindDir()).append('\n')
//                .append("风力等级：").append(bean.getWindScale()).append(" (").append(getWindName(Integer.parseInt(bean.getWindScale()))).append(")\n")
//                .append("风速：").append(bean.getWindSpeed()).append(" km/h\n")
//                .append("相对湿度：").append(bean.getHumidity()).append('\n')
//                .append("降水量：").append(bean.getPrecip()).append(" 毫米\n")
//                .append("大气压强：").append(bean.getPressure()).append(" 百帕\n")
//                .append("能见度：").append(bean.getVis()).append(" 公里\n")
//                .append("云量：").append(bean.getCloud()).append('\n')
//                .append("露点温度：").append(bean.getDew()).append('\n');
//        tvWeatherNow.setText(sb.toString());
        ivWeatherNowIcon.setImageResource(IconUtil.getIconID(bean.getIcon()));
        tvWeatherNowText.setText(bean.getText());
        tvWeatherNowTemp.setText(bean.getTemp() + " ℃");
        tvWeatherNowOther.setText(getWindName(Integer.parseInt(bean.getWindScale())) + " 降水" + bean.getPrecip() + "mm");
        Toast.makeText(getContext(), "getWeatherNow success", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void getWeather24H(WeatherHourlyBean weatherHourlyBean) {
        Log.d(TAG, "getWeather24H " + StringUtil.isNull(weatherHourlyBean));
        if (weatherHourlyBean == null) return;

        List<WeatherHourlyBean.HourlyBean> hourlyBeans = weatherHourlyBean.getHourly();
//        StringBuilder sb = new StringBuilder();
//        for (WeatherHourlyBean.HourlyBean bean : hourlyBeans) {
//            sb
//                    .append("预报时间：").append(bean.getFxTime()).append('\n')
//                    .append("温度：").append(bean.getTemp()).append(" ℃\n")
//                    .append("图标代码：").append(bean.getIcon()).append('\n')
//                    .append("文字描述：").append(bean.getText()).append('\n')
//                    .append("风向（360度）：").append(bean.getWind360()).append('\n')
//                    .append("风向：").append(bean.getWindDir()).append('\n')
//                    .append("风力等级：").append(bean.getWindScale()).append(" (").append(bean.getWindScale()).append(")\n")
//                    .append("风速：").append(bean.getWindSpeed()).append(" km/h\n")
//                    .append("相对湿度：").append(bean.getHumidity()).append('\n')
//                    .append("降水概率:").append(bean.getPop()).append('\n')
//                    .append("降水量：").append(bean.getPrecip()).append(" 毫米\n")
//                    .append("大气压强：").append(bean.getPressure()).append(" 百帕\n")
//                    .append("云量：").append(bean.getCloud()).append('\n')
//                    .append("露点温度：").append(bean.getDew()).append('\n')
//                    .append("\n");
//        }
//        tvWeatherHourly.setText(sb.toString());
        rvWeatherHourlyAdapter.setHourlyBeanList(hourlyBeans);
        rvWeatherHourlyAdapter.notifyDataSetChanged();
//        rvWeatherHourly.setAdapter(rvWeatherHourlyAdapter);
        Toast.makeText(getContext(), "getWeather24H success", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void getWeather7D(WeatherDailyBean weatherDailyBean) {
        Log.d(TAG, "getWeather7D " + StringUtil.isNull(weatherDailyBean));
        if (weatherDailyBean == null) return;

        rvWeather7DAdapter.setDailyBeans(weatherDailyBean.getDaily());
        rvWeather7DAdapter.notifyDataSetChanged();
        Toast.makeText(getContext(), "getWeather7D success", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void getAqiNow(AqiNowBean aqiNowBean) {
        Log.d(TAG, "getAqiNow " + StringUtil.isNull(aqiNowBean));
        if (aqiNowBean == null) return;

        AqiNowBean.Index index = aqiNowBean.getIndexes().get(0);
        String aqiNowText = "空气质量指数：" + index.getAqi() + "\n";
        // 国内支持的AQI有 cn-mee cn-mee-1h
        if ("cn-mee".equals(index.getCode()) || "cn-mee-1h".equals(index.getCode())) {
            final int[] thresholds = {-1, 50, 100, 150, 200, 300, 500};
            final String[] desc = {"", "优", "良", "轻度污染", "中度污染", "重度污染", "严重污染", "严重污染"};
            int aqiValue = Integer.parseInt(index.getAqi());
            int level = 0;
            for (int t : thresholds) {
                if (aqiValue <= t) break;
                else level++;
            }
            aqiNowText += desc[level];
        }
        tvAqiNow.setText(aqiNowText);

        StringBuilder name = new StringBuilder();
        StringBuilder value = new StringBuilder();
        for (AqiNowBean.Pollutant p : aqiNowBean.getPollutants()) {
            name.append(p.getName()).append("\n");
            value.append(p.getConcentration().getValue()).append(p.getConcentration().getUnit()).append("\n");
        }
        tvAqiNowPollutantName.setText(name.toString());
        tvAqiNowPollutantValue.setText(value.toString());
        Toast.makeText(getContext(), "getAqiNow success", Toast.LENGTH_SHORT).show();
    }

    @Override
    public Context getContext() {
        return WeatherActivity.this;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater menuInflater = getMenuInflater();
        menuInflater.inflate(R.menu.main_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.mi_update_weather) {
            updateLocation(currentLocationBean);
        } else if (id == R.id.mi_select_city) {
            launcherGetLocation.launch(new Intent(this, SelectCityActivity.class));
        } else if (id == R.id.mi_search_location) {
            launcherGetLocation.launch(new Intent(this, SearchLocationActivity.class));
        } else if (id == R.id.mi_saved_cities) {
            launcherGetLocation.launch(new Intent(this, SaveCityActivity.class));
        } else {
            return super.onOptionsItemSelected(item);
        }
        return true;
    }
}